package com.bitmain.mmst.miner.monitor.executor;

import java.net.InetAddress;
import java.util.function.Supplier;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.log4j.Logger;

import com.bitmain.ulnar.aider.JSONAider;
import com.bitmain.ulnar.aider.http.HTTPClientSide;
import com.bitmain.ulnar.aider.http.HTTPRequestMessage;
import com.bitmain.ulnar.aider.http.HTTPResponseMessage;
/**
 * 
 *
 * @author Richard - rui.wu@bitmain.com
 * @param <T>
 * @since 2016��7��4�� 
 *
 */
public abstract class AbstractMinerExecutor<E extends AbstractMinerExecutor<E, T>, T> implements Supplier<T> {
	protected Logger logger;
	
	//private static final String MINER_SSH_USERNAME = "root"; 
	//private static final String MINER_SSH_PASSWORD = "admin"; 
	private static final String MINER_HTTP_USERNAME = "root"; 
	private static final String MINER_HTTP_PASSWORD = "root"; 
	
	public AbstractMinerExecutor(Class<E> clazz){
		logger = Logger.getLogger(clazz);
	}
	public boolean pingMiner(String ip){
		boolean reachable = false;
		try {
			reachable = InetAddress.getByName(ip).isReachable(3000);
		} catch (Exception e) {
			System.out.println("Failed ping");
		}
		return reachable;
	}
	
	/**
	 * 判断矿机是否存在 （使用ping命令检测数据包是否能通过IP协议到达矿机，指定ping命令执行次数）。
	 * 
	 * @param ip 矿机的IP地址
	 * @param attempts 检测次数（ping命令执行次数）
	 * @return true存在；false不存在
	 * @see #pingMiner(String)
	 */
	public boolean pingMiner(String ip, int attempts) {
		boolean reachable = false;
		for (int i=1; i<=attempts; i++) {
			reachable = pingMiner(ip);
			if (reachable) {
				break;
			}
		}
		return reachable;
	}
	
	public String getMinerMac(String ip){
		String mac = null;
		String content = null;
		try {
			String url = "http://" + ip + "/cgi-bin/get_network_info.cgi";
			
			CredentialsProvider credsProvider = new BasicCredentialsProvider();
			credsProvider.setCredentials(new AuthScope(ip, 80), new UsernamePasswordCredentials(MINER_HTTP_USERNAME, MINER_HTTP_PASSWORD));
			HttpClientContext context = new HttpClientContext();
	        context.setAttribute(HttpClientContext.CREDS_PROVIDER, credsProvider);
	        
	        HTTPRequestMessage request = new HTTPRequestMessage();
	        request.setUrl(url);
	        HTTPResponseMessage response = HTTPClientSide.get(request, context, 3000);
	        content = response.getContent();
	        if (StringUtils.isNotBlank(content)) {
	        	mac = JSONAider.getString(content, "macaddr");
	        }
		} catch (Exception e) {
//			if (StringUtils.isNotBlank(content)) {
//				content = content.replace("\r\n", "");
//			}
//			logger.error("getMinerMAC error - content : " + content);
		}
		return mac;
	}
	@Override
	public T get() {
		return execute();
	}
	
	public abstract T execute();
}
